package com.zjw.zy.coreui.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

import com.zjw.zy.utils.LogUtils;
import com.zjw.zy.utils.TimeUtils;
import com.zjw.zy.utils.taskpool.TaskPool;

import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * @author ：zhong.jw
 * @date ：Created in 2022/12/29 13:16
 * <p>
 * 播放视频的view
 */
public class RadioView extends SurfaceView implements SurfaceHolder.Callback {


    private static final String TAG = "RadioView";

    private final Executor mExecutor = Executors.newSingleThreadExecutor();

    private boolean isInit = false;

    private MediaPlayer mediaPlayer;

    private Listener listener;

    private Disposable progressTask;

    public RadioView(Context context) {
        super(context);

        onInit();
    }

    public RadioView(Context context, AttributeSet attrs) {
        super(context, attrs);

        onInit();
    }

    public RadioView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        onInit();
    }

    public RadioView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        onInit();
    }


    public void play(String path) {
        LogUtils.d(TAG, "play " + path);
        playImpl(path);
    }

    public void pause() {
        LogUtils.d(TAG, "pause");

        pauseImpl();
    }

    public void stop() {
        LogUtils.d(TAG, "stop");

        stopImpl();
    }

    private void stopImpl() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }

        if (progressTask != null) {
            progressTask.dispose();
            progressTask = null;
        }
    }

    private void pauseImpl() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
        if (progressTask != null) {
            progressTask.dispose();
            progressTask = null;
        }
    }

    private void playImpl(String path) {
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
        }

        mediaPlayer.reset();

        mediaPlayer.setOnErrorListener((mp, what, extra) -> {
            LogUtils.d(TAG, "onError " + what);
            return true;
        });

        mediaPlayer.setOnPreparedListener(mp -> {
            LogUtils.d(TAG, "start play");
            mp.start();

            onNotifyProgress();
        });

        try {
            mediaPlayer.setDataSource(path);
        } catch (IOException e) {
            LogUtils.e(TAG, e.getMessage());
        }
    }

    private void onNotifyProgress() {
        LogUtils.d(TAG, "onNotifyProgress");

        if (mediaPlayer != null) {
            if (listener != null) {
                listener.onProgressTotal(mediaPlayer.getDuration());
            }
        }
        if (progressTask != null) {
            progressTask.dispose();
            progressTask = null;
        }
        progressTask = Observable.interval(0, 100, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.computation())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(a -> {
                    if (mediaPlayer != null) {
                        int total = mediaPlayer.getDuration();
                        int position = mediaPlayer.getCurrentPosition();
                        if (listener != null) {
                            listener.onProgress(position);
                        }
                    }
                });
    }

    private void onInit() {
        if (isInit) {
            return;
        }

        isInit = true;

        LogUtils.d(TAG, "onInit");
        getHolder().addCallback(this);
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        LogUtils.d(TAG, "surfaceCreated");
        if (mediaPlayer != null) {
            mediaPlayer.setDisplay(holder);

            LogUtils.d(TAG, "prepareAsync");
            mediaPlayer.prepareAsync();
        }
    }


    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        LogUtils.d(TAG, "surfaceChanged width->" + width + " height->" + height);
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        LogUtils.d(TAG, "surfaceDestroyed");

        stop();
    }

    public void bindListener(Listener listener) {
        this.listener = listener;
    }

    public void resume() {
        LogUtils.d(TAG, "resume");
        resumeImpl();
    }

    private void resumeImpl() {
        if (mediaPlayer != null && !mediaPlayer.isPlaying()) {
            mediaPlayer.start();

            onNotifyProgress();
        }
    }

    public void progress(int position) {
        LogUtils.d(TAG, "progressImpl() called with: position = [" + position + "]");

        progressImpl(position);
    }

    private void progressImpl(int position) {
        if (mediaPlayer != null) {
            mediaPlayer.seekTo(position);
        }
    }

    public interface Listener {

        void onProgress(int progress);

        void onProgressTotal(int total);
    }
}
